home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows 95 - 300 Programs & More
/
Windows 95 - 300 Programs & More.iso
/
misc
/
sysclick
/
iconwnd.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-25
|
13KB
|
498 lines
// ************************************************************
//
// System-Click Notification Icon
// Win95 32-bit Shell Extension
// James P. Ketrenos
//
// ************************************************************
#include <afx.h>
#include <shlobj.h> // SHAddToRecentDocs()
// NOTE: I had to comment out line 139 in OAIDL.H in order to get it to compile with shlobj.h.
// The line commented out redefined BSTR
#include "Resource.h"
#include "Global.h"
#include "IconWnd.h"
// ************************************************************
// CIconWnd Class Implementation
//
// Purpose:
// * Respond to Notification Button actions.
// * Respond to WM_WININICHANGE messages to keep tool-tip
// up to date.
// * Keep the system INI and registry up to date with all
// the latest values as we change them.
// ************************************************************
BEGIN_MESSAGE_MAP(CIconWnd, CFrameWnd)
ON_COMMAND(IDC_FULLDRAG, OnFullDrag)
ON_COMMAND(IDC_ANIMATED, OnAnimated)
ON_COMMAND(IDC_CLRDOCS, OnClearDocs)
ON_COMMAND(IDC_ABOUT, OnAbout)
ON_COMMAND(IDC_APPHELP, OnHelp)
ON_COMMAND(IDCLOSE, OnClose)
ON_MESSAGE(SC_WM_NOTIFYICON, OnNotifyIcon)
ON_WM_DESTROY()
ON_WM_TIMER()
ON_WM_WININICHANGE()
END_MESSAGE_MAP()
// ************************************************************
// Message-Mapped Functions
// ************************************************************
// *******************************
// CIconWnd::OnWinIniChange()
//
// Purpose:
// * Respond to the system WM_WININICHANGE message
// * If the [Windows] section has been altered, re-fetch
// our settings from the system and update our variables.
// * Update the Notification Icon accordingly
// *******************************
void CIconWnd::OnWinIniChange(LPCTSTR lpszSection)
{
CString String = "WINDOWS";
if (!String.CompareNoCase(lpszSection))
{
m_Fetch();
m_UpdateIconTip();
// Check to see if Windows Extension #1 is installed
m_bExtension1 = SystemParametersInfo(SPI_GETWINDOWSEXTENSION, 1, 0, 0);
}
}
// *******************************
// CIconWnd::OnAbout()
//
// Purpose:
// * Check to see if our About window is already up.
// + If so, make the current one the foreground active window
// + If not, create the About window and display it.
// *******************************
void CIconWnd::OnAbout()
{
CWnd* pWnd = FindWindow(NULL, "About System-Click . . .");
if (!pWnd)
{
CDialog About(IDD_ABOUT, this);
About.DoModal();
}
else
pWnd->SetForegroundWindow();
}
// *******************************
// CIconWnd::OnHelp()
//
// Purpose:
// * Check to see if our Help window is already up.
// + If so, make the current one the foreground active window
// + If not, create the Help window and display it.
// *******************************
void CIconWnd::OnHelp()
{
CWnd* pWnd = FindWindow(NULL, "System-Click Help");
if (!pWnd)
{
CDialog Help(IDD_HELP, this);
Help.DoModal();
}
else
pWnd->SetForegroundWindow();
}
// *******************************
// CIconWnd::OnClearDocs()
//
// Purpose:
// * Clears the Recent Document list in the Start Menus
// *******************************
void CIconWnd::OnClearDocs()
{
// Clears the document list
::SHAddToRecentDocs(NULL, NULL);//SHARD_PATH, NULL); //SHARD_PIDL, NULL);
}
// *******************************
// CIconWnd::OnAnimated()
//
// Purpose:
// * Toggle the Animated Window flag
// * Update the Notification Icon Tool-Tip to reflect current state
// * Update the Win95 system parameters
// *******************************
void CIconWnd::OnAnimated()
{
ANIMATIONINFO Animated;
m_bAnimated = (m_bAnimated ? FALSE : TRUE);
m_UpdateIconTip();
// Update the system parameter, save the setting in the Windows INI file, and let
// all top level windows know we have changed a system parameter.
Animated.cbSize = sizeof(ANIMATIONINFO);
Animated.iMinAnimate = m_bAnimated;
SystemParametersInfo(
SPI_SETANIMATION,
0,
&Animated,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
}
// *******************************
// CIconWnd::OnFullDrag()
//
// Purpose:
// * Toggle the Full Dragging flag
// * Update the Notification Icon Tool-Tip to reflect current state
// * Update the Win95 system parameters
// *******************************
void CIconWnd::OnFullDrag()
{
m_bFullDrag = (m_bFullDrag ? FALSE : TRUE);
m_UpdateIconTip();
// Update the system parameter, save the setting in the Windows INI file, and let
// all top level windows know we have changed a system parameter.
SystemParametersInfo(
SPI_SETDRAGFULLWINDOWS,
m_bFullDrag,
0,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
}
// ************************************************************
// General Class Functions
// ************************************************************
// *******************************
// CIconWnd::CIconWnd()
//
// Purpose:
// * Place keeper
// *******************************
CIconWnd::CIconWnd()
{
}
// *******************************
// CIconWnd::~CIconWnd()
//
// Purpose:
// * Place keeper
// *******************************
CIconWnd::~CIconWnd()
{
}
// *******************************
// CIconWnd::m_UpdateIconTip()
//
// Purpose:
// * Updates the Notification Icon Tool-Tip to refelct
// current variable states.
// *******************************
void CIconWnd::m_UpdateIconTip()
{
NOTIFYICONDATA nidSysClk;
nidSysClk.cbSize = sizeof(NOTIFYICONDATA);
nidSysClk.hWnd = AfxGetApp()->m_pMainWnd->GetSafeHwnd();
nidSysClk.uID = IDI_SYSCLK;
nidSysClk.uFlags = NIF_TIP;
wsprintf(
nidSysClk.szTip,
"FD: %s AW: %s",
m_bFullDrag ? "ON" : "OFF",
m_bAnimated ? "ON" : "OFF");
Shell_NotifyIcon(NIM_MODIFY, &nidSysClk);
}
// *******************************
// CIconWnd::m_Fetch()
//
// Purpose:
// * Fetch system settings from Win95
// *******************************
void CIconWnd::m_Fetch()
{
ANIMATIONINFO Animated;
SystemParametersInfo(
SPI_GETDRAGFULLWINDOWS,
0,
&m_bFullDrag,
0);
Animated.cbSize = sizeof(ANIMATIONINFO);
SystemParametersInfo(
SPI_GETANIMATION,
0,
&Animated,
0);
m_bAnimated = Animated.iMinAnimate ? TRUE : FALSE;
}
// *******************************
// CIconWnd::OnTimer()
//
// Purpose:
// * Called .5 seconds after the Notification Icon is activated
// * Provide functionality for Notification Icon
// * Keeps stray mouse button clicks from dismissing menu before
// it has displayed.
// *******************************
void CIconWnd::OnTimer(UINT nIDEvent)
{
if (nIDEvent == IDT_CLOSE)
{
SendMessage(WM_CLOSE);
}
if (nIDEvent == IDT_POPUP)
{
CMenu hPopup;
POINT Point;
HWND hOrigActive;
// Kill the timer
KillTimer(m_Timer);
m_Timer = 0;
// Create our menu
hPopup.CreatePopupMenu();
if (m_bExtension1) // Requires Extension1 Pack to be installed
hPopup.AppendMenu(MF_STRING, IDC_FULLDRAG, "&Full Drag");
// Standard Win95 functionality
hPopup.AppendMenu(MF_STRING, IDC_ANIMATED, "&Animated Windows");
hPopup.AppendMenu(MF_STRING, IDC_CLRDOCS, "&Clear Recent Doc List");
// Generic program menu items
hPopup.AppendMenu(MF_SEPARATOR);
hPopup.AppendMenu(MF_STRING, IDC_ABOUT, "A&bout . . .");
hPopup.AppendMenu(MF_STRING, IDC_APPHELP, "&Help");
//hPopup.AppendMenu(MF_STRING, IDCLOSE, "E&xit");
// Set the initial checks correctly
hPopup.CheckMenuItem(IDC_ANIMATED, MF_BYCOMMAND | (m_bAnimated ? MF_CHECKED : MF_UNCHECKED));
if (m_bExtension1)
hPopup.CheckMenuItem(IDC_FULLDRAG, MF_BYCOMMAND | (m_bFullDrag ? MF_CHECKED : MF_UNCHECKED));
// Get the currently active window, set our window to active, pop up the menu, and
// then return the system state to the way it was.
hOrigActive = ::GetForegroundWindow();
SetForegroundWindow();
::GetCursorPos(&Point);
hPopup.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, Point.x, Point.y, this, NULL);
::SetForegroundWindow(hOrigActive);
// Destroy our menu to insure our resources are freed
hPopup.DestroyMenu();
return;
}
}
// *******************************
// CIconWnd::OnNotifyIcon()
//
// Purpose:
// * Notification Icon callback function
// * If the user left clicks on the icon, pop up the toggle button window.
// * If the user double-clicks on the icon, toggle the current mode.
//
// NOTE: Because of the magic in Win95, it is better not to do any actual
// processing immediately after we encounter our message from the
// Notification Icon.
//
// It is better to trigger a Timer and respond to the WM_TIMER message.
// This gives the system enough time to flush out the stray mouse
// messages before our code actually takes place.
//
// It appears as if the OS gives our program the mouse messages first, and
// then hands them to the Taskbar after we take them. If we do not wait
// and immediately do a TrackPopupMenu(), the stray mouse clicks may
// dismiss this menu. Likewise, if we close the application immediately,
// the mouse clicks that triggered our app to shutdown will be fed to
// the task bar and may cause adverse effects.
// *******************************
LONG CIconWnd::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
{
UINT uID;
UINT uMsg;
BOOL bFDOriginal = m_bFullDrag;
BOOL bAWOriginal = m_bAnimated;
uID = (UINT)wParam;
uMsg = (UINT)lParam;
if ((uMsg == WM_RBUTTONDBLCLK) && (uID == IDI_SYSCLK))
{
m_Timer = SetTimer(IDT_CLOSE, 500, NULL);
return 0L;
}
if ((uMsg == WM_LBUTTONDOWN) && (uID == IDI_SYSCLK))
{
m_Timer = SetTimer(IDT_POPUP, 500, NULL);
return 0L;
}
return 0L;
}
// *******************************
// CIconWnd::m_InitIcon()
//
// Purpose:
// * Fetch the Full-Drag option from our INI file
// * Initialize the Notification Icon
// * Set the SystemParameterInfo() setting for the Full Dragging
// accordingly.
// Returns:
// TRUE Success
// FALSE Failure, either from Shell_NotifyIcon
// *******************************
BOOL CIconWnd::m_InitIcon()
{
NOTIFYICONDATA nidSysClk;
BOOL bRetVal;
HICON hIcon;
ANIMATIONINFO Animated;
// Fetch entries from our INI file [defaults = FALSE]
// NOTE: We don't do this since all our settings are saved in the
// windows INI and in the registry.
//m_bFullDrag = AfxGetApp()->GetProfileInt("General", "Full Drag", 0);
//m_bAnimated = AfxGetApp()->GetProfileInt("General", "Animated", 0);
// Fetch current values from the System settings
m_Fetch();
// Latch the Notification Icon into the Notification Area
hIcon = AfxGetApp()->LoadIcon(MAKEINTRESOURCE(IDI_SYSCLK));
nidSysClk.cbSize = sizeof(NOTIFYICONDATA);
nidSysClk.hWnd = GetSafeHwnd();
nidSysClk.uID = IDI_SYSCLK;
nidSysClk.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
nidSysClk.uCallbackMessage = SC_WM_NOTIFYICON;
nidSysClk.hIcon = hIcon;
wsprintf(
nidSysClk.szTip,
"FD: %s AW: %s",
m_bFullDrag ? "ON" : "OFF",
m_bAnimated ? "ON" : "OFF");
bRetVal = Shell_NotifyIcon(NIM_ADD, &nidSysClk);
if (hIcon)
DestroyIcon(hIcon);
// Update the system parameter, save the setting in the Windows INI file, and let
// all top level windows know we have changed a system parameter.
SystemParametersInfo(
SPI_SETDRAGFULLWINDOWS,
m_bFullDrag,
0,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
Animated.cbSize = sizeof(ANIMATIONINFO);
Animated.iMinAnimate = m_bAnimated;
SystemParametersInfo(
SPI_SETANIMATION,
0,
&Animated,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
return bRetVal;
}
// *******************************
// CIconWnd::OnDestroy()
//
// Purpose:
// * Delete the notification icon from the Notification area.
// * Save the System-Click setting to our INI setting.
//
// *******************************
void CIconWnd::OnDestroy()
{
NOTIFYICONDATA nidSysClk;
// Verify that we do not have a timer allocated
if (m_Timer)
{
KillTimer(m_Timer);
m_Timer = 0;
}
// Remove the Notification Icon from the Notification area
nidSysClk.cbSize = sizeof(NOTIFYICONDATA);
nidSysClk.hWnd = GetSafeHwnd();
nidSysClk.uID = IDI_SYSCLK;
Shell_NotifyIcon(NIM_DELETE, &nidSysClk);
// Save our setting to the INI file
// NOTE: We don't do this since all our settings are saved in the
// windows INI and in the registry.
//AfxGetApp()->WriteProfileInt("General", "SysClk", m_bFullDrag);
//AfxGetApp()->WriteProfileInt("General", "Animated", m_bAnimated);
CWnd::OnDestroy();
}